"use strict";
cc._RF.push(module, '12f58/ynMlCE6VHe1FVRNnL', 'game');
// Sprite/game.js

'use strict';

var ROWS = 4;
var NUMBERS = [2, 4];
var MIN_LENGTH = 10;
var MOVE_DURATION = 0.05;

cc.Class({
    extends: cc.Component,

    properties: {
        scoreLable: cc.Label,
        score: 0,
        blockPrefab: cc.Prefab,
        gap: 10,
        bg: cc.Node,
        gameOverBg: cc.Node,
        aginBtn: cc.Node
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    start: function start() {
        this.drawBlock();
        this.init();
    },

    //绘制方块
    drawBlock: function drawBlock() {
        this.blockSize = (cc.winSize.width - this.gap * (ROWS + 1)) / ROWS;
        var x = this.blockSize / 2 + this.gap;
        var y = this.blockSize + this.gap;
        this.positions = [];

        for (var i = 0; i < ROWS; i++) {
            this.positions.push([0, 0, 0, 0]);
            for (var j = 0; j < ROWS; j++) {
                var block = cc.instantiate(this.blockPrefab);
                block.width = this.blockSize;
                block.height = this.blockSize;
                this.bg.addChild(block);
                //储存每个块的坐标
                this.positions[i][j] = cc.v2(x, y);
                block.setPosition(cc.v2(x, y));
                block.getComponent('block').setNumber(0);
                x += this.blockSize + this.gap;
            }
            x = this.blockSize / 2 + this.gap;
            y += this.blockSize + this.gap;
        }
    },
    init: function init() {
        this.updateScore(0);

        //重置块数组和分数组
        if (this.blocks) {
            for (var _i = 0; _i < ROWS; _i++) {
                for (var _j = 0; _j < ROWS; _j++) {
                    if (this.blocks[_i][_j]) this.blocks[_i][_j].destroy();
                }
            }
        }

        this.blocks = [];
        this.data = [];
        for (var i = 0; i < ROWS; i++) {
            var xArr = [],
                xNum = [];
            for (var j = 0; j < ROWS; j++) {
                xArr.push(null);
                xNum.push(0);
            }
            this.blocks.push(xArr);
            this.data.push(xNum);
        }

        //添加新的块
        this.addBlock(3);
        //监听拖拽
        this.addEventHandler();
    },

    //更新分数
    updateScore: function updateScore(number) {
        this.scoreLable.string = "分数：" + number;
        this.score = number;
    },

    /**
     * 找出空闲块
     * return 带有位置xy坐标的空闲块数组
     */
    getEnptyBlock: function getEnptyBlock() {
        var emptyPos = [];
        for (var row = 0; row < ROWS; row++) {
            for (var col = 0; col < ROWS; col++) {
                if (this.blocks[row][col] == null) {
                    emptyPos.push({ 'x': row, 'y': col });
                }
            }
        }
        return emptyPos;
    },

    /**
     * 添加块
     * @param {添加块的数量} n 
     */
    addBlock: function addBlock(n) {
        for (var i = 0; i < n; i++) {
            var locations = this.getEnptyBlock();
            if (locations.length == 0) return false;
            var location = locations[Math.floor(Math.random() * locations.length)];
            var row = location.x;
            var col = location.y;
            //实例化预制体
            var block = cc.instantiate(this.blockPrefab);
            block.width = this.blockSize;
            block.height = this.blockSize;
            this.bg.addChild(block);
            block.setPosition(this.positions[row][col]);
            var number = NUMBERS[Math.floor(Math.random() * NUMBERS.length)];
            block.getComponent('block').setNumber(number);
            //记录本次出现的块和数字
            this.blocks[row][col] = block;
            this.data[row][col] = number;
        }
    },
    addEventHandler: function addEventHandler() {
        var _this = this;

        this.bg.on("touchstart", function (event) {
            _this.startPoint = event.getLocation();
        });
        this.bg.on("touchend", function (event) {
            _this.touchEnd(event);
        });
        this.bg.on("touchcancel", function (event) {
            _this.touchEnd(event);
        });
    },
    touchEnd: function touchEnd(event) {
        this.endPoint = event.getLocation();
        var offset = this.endPoint.sub(this.startPoint);
        if (Math.abs(offset.mag()) > 0) {
            if (Math.abs(offset.x) > Math.abs(offset.y)) {
                //横向
                if (offset.x > 0) {
                    this.moveRight();
                } else {
                    this.moveLeft();
                }
            } else {
                //垂直
                if (offset.y > 0) {
                    this.moveUp();
                } else {
                    this.moveDown();
                }
            }
        }
    },

    /**
     * 移动完毕后
     */
    afterMove: function afterMove(hasMoved) {
        //判断是否需要新增块
        if (hasMoved) {
            this.updateScore(this.score + 1);
            this.addBlock(1);
        }
        //判断是否游戏结束
        if (this.checkFail()) {
            this.gameOver();
        }
    },

    /**
     * 游戏结束
     */
    gameOver: function gameOver() {
        var _this2 = this;

        this.gameOverBg.zIndex = 1000;
        this.gameOverBg.active = true;
        this.aginBtn.on('touchstart', function () {
            _this2.gameOverBg.active = false;
            _this2.init();
        });
    },


    /**
     * 移动格子操作
     */
    doMove: function doMove(block, position, callback) {
        var action = cc.moveTo(MOVE_DURATION, position);
        var finish = cc.callFunc(function () {
            callback && callback();
        });
        block.runAction(cc.sequence(action, finish));
    },

    /**
     * 检查游戏结束
     */
    checkFail: function checkFail() {
        for (var i = 0; i < ROWS; i++) {
            for (var j = 0; j < ROWS; j++) {
                var n = this.data[i][j];
                if (n == 0) {
                    cc.log('0');return false;
                };
                if (j > 0 && this.data[i][j - 1] == n) {
                    cc.log('left');return false;
                }; //是否还能往左
                if (j < ROWS - 1 && this.data[i][j + 1] == n) {
                    cc.log('right');return false;
                }; //是否还能往右
                if (i < ROWS - 1 && this.data[i + 1][j] == n) {
                    cc.log('up');return false;
                }; //是否还能往上
                if (i > 0 && this.data[i - 1][j] == n) {
                    cc.log('down');return false;
                }; //是否还能往下
            }
        }
        return true;
    },
    moveLeft: function moveLeft() {
        var _this3 = this;

        cc.log(' left ');
        var toMove = [];
        var hasMoved = false;

        //获取所有可移动的块，从左往右装块
        for (var i = 0; i < ROWS; i++) {
            for (var j = 0; j < ROWS; j++) {
                if (this.data[i][j] != 0) {
                    toMove.push({ x: i, y: j });
                }
            }
        }

        var move = function move(x, y, callback) {
            if (y == 0 || _this3.data[x][y] == 0) {
                //自己已经是最边上了，自己是空的块
                callback && callback(); //上报afgerMove
                return;
            } else if (_this3.data[x][y - 1] == _this3.data[x][y]) {
                //可以与左边合并
                //合并
                cc.log('合并');
                var block = _this3.blocks[x][y];
                var position = _this3.positions[x][y];
                _this3.data[x][y - 1] *= 2;
                _this3.blocks[x][y - 1].getComponent('block').setNumber(_this3.data[x][y - 1]);
                _this3.blocks[x][y] = null;
                _this3.data[x][y] = 0;
                _this3.doMove(block, position, function () {
                    block.destroy();
                    callback && callback();
                });
                hasMoved = true;
            } else if (_this3.data[x][y - 1] == 0) {
                //左边一格什么都没有
                //移动
                cc.log('移动');
                var _block = _this3.blocks[x][y];
                var _position = _this3.positions[x][y - 1]; //左边的那个格子
                _this3.blocks[x][y - 1] = _block;
                _this3.data[x][y - 1] = _this3.data[x][y];
                _this3.data[x][y] = 0;
                _this3.blocks[x][y] = null;
                _this3.doMove(_block, _position, function () {
                    move(x, y - 1, callback);
                });
                hasMoved = true;
            } else {
                callback && callback(); //上报afgerMove
                return;
            }
        };

        //移动这些块
        var counter = 0;
        for (var _i2 = 0; _i2 < toMove.length; _i2++) {
            move(toMove[_i2].x, toMove[_i2].y, function () {
                ++counter;
                if (counter == toMove.length) {
                    _this3.afterMove(hasMoved);
                }
            });
        }
    },
    moveRight: function moveRight() {
        var _this4 = this;

        cc.log(' right ');

        var toMove = [];
        var hasMoved = false;

        //获取所有可移动的块，从右往左装块
        for (var i = 0; i < ROWS; i++) {
            for (var j = ROWS - 1; j >= 0; j--) {
                if (this.data[i][j] != 0) {
                    toMove.push({ x: i, y: j });
                }
            }
        }

        var move = function move(x, y, callback) {
            if (y == ROWS - 1 || _this4.data[x][y] == 0) {
                //自己已经是最边上了，自己是空的块
                callback && callback();
                return;
            } else if (_this4.data[x][y + 1] == _this4.data[x][y]) {
                //可以与右边合并
                //合并
                cc.log('合并');
                var block = _this4.blocks[x][y];
                var position = _this4.positions[x][y];
                _this4.data[x][y + 1] *= 2;
                _this4.blocks[x][y + 1].getComponent('block').setNumber(_this4.data[x][y + 1]);
                _this4.blocks[x][y] = null;
                _this4.data[x][y] = 0;
                _this4.doMove(block, position, function () {
                    block.destroy();
                    callback && callback();
                });
                hasMoved = true;
            } else if (_this4.data[x][y + 1] == 0) {
                //右边一格什么都没有
                //移动
                cc.log('移动');
                var _block2 = _this4.blocks[x][y];
                var _position2 = _this4.positions[x][y + 1]; //右边的那个格子
                _this4.blocks[x][y + 1] = _block2;
                _this4.data[x][y + 1] = _this4.data[x][y];
                _this4.data[x][y] = 0;
                _this4.blocks[x][y] = null;
                _this4.doMove(_block2, _position2, function () {
                    move(x, y + 1, callback);
                });
                hasMoved = true;
            } else {
                callback && callback();
                return;
            }
        };

        //移动这些块
        var counter = 0;
        for (var _i3 = 0; _i3 < toMove.length; _i3++) {
            move(toMove[_i3].x, toMove[_i3].y, function () {
                ++counter;
                if (counter == toMove.length) {
                    _this4.afterMove(hasMoved);
                }
            });
        }
    },
    moveUp: function moveUp() {
        var _this5 = this;

        cc.log(' up ');

        var toMove = [];
        var hasMoved = false;

        //获取所有可移动的块，从上往下装
        for (var i = ROWS - 1; i >= 0; i--) {
            for (var j = 0; j < ROWS; j++) {
                if (this.data[i][j] != 0) {
                    toMove.push({ x: i, y: j });
                }
            }
        }

        var move = function move(x, y, callback) {
            if (x == ROWS - 1 || _this5.data[x][y] == 0) {
                //自己已经是最边上了，自己是空的块
                callback && callback();
                return;
            } else if (_this5.data[x + 1][y] == _this5.data[x][y]) {
                //可以与上边合并
                //合并
                cc.log('合并');
                var block = _this5.blocks[x][y];
                var position = _this5.positions[x][y];
                _this5.data[x + 1][y] *= 2;
                _this5.blocks[x + 1][y].getComponent('block').setNumber(_this5.data[x + 1][y]);
                _this5.blocks[x][y] = null;
                _this5.data[x][y] = 0;
                _this5.doMove(block, position, function () {
                    block.destroy();
                    callback && callback();
                });
                hasMoved = true;
            } else if (_this5.data[x + 1][y] == 0) {
                //上边一格什么都没有
                //移动
                cc.log('移动');
                var _block3 = _this5.blocks[x][y];
                var _position3 = _this5.positions[x + 1][y]; //上边的那个格子
                _this5.blocks[x + 1][y] = _block3;
                _this5.data[x + 1][y] = _this5.data[x][y];
                _this5.data[x][y] = 0;
                _this5.blocks[x][y] = null;
                _this5.doMove(_block3, _position3, function () {
                    move(x + 1, y, callback);
                });
                hasMoved = true;
            } else {
                callback && callback();
                return;
            }
        };

        //移动这些块
        var counter = 0;
        for (var _i4 = 0; _i4 < toMove.length; _i4++) {
            move(toMove[_i4].x, toMove[_i4].y, function () {
                ++counter;
                if (counter == toMove.length) {
                    _this5.afterMove(hasMoved);
                }
            });
        }
    },
    moveDown: function moveDown() {
        var _this6 = this;

        cc.log(' down ');

        var toMove = [];
        var hasMoved = false;

        //获取所有可移动的块，从下往上装
        for (var i = 0; i < ROWS; i++) {
            for (var j = ROWS - 1; j >= 0; j--) {
                if (this.data[i][j] != 0) {
                    toMove.push({ x: i, y: j });
                }
            }
        }

        var move = function move(x, y, callback) {
            if (x == 0 || _this6.data[x][y] == 0) {
                //自己已经是最边下了，自己是空的块
                callback && callback();
                return;
            } else if (_this6.data[x - 1][y] == _this6.data[x][y]) {
                //可以与下边合并
                //合并
                cc.log('合并');
                var block = _this6.blocks[x][y];
                var position = _this6.positions[x][y];
                _this6.data[x - 1][y] *= 2;
                _this6.blocks[x - 1][y].getComponent('block').setNumber(_this6.data[x - 1][y]);
                _this6.blocks[x][y] = null;
                _this6.data[x][y] = 0;
                _this6.doMove(block, position, function () {
                    block.destroy();
                    callback && callback();
                });
                hasMoved = true;
            } else if (_this6.data[x - 1][y] == 0) {
                //下边一格什么都没有
                //移动
                cc.log('移动');
                var _block4 = _this6.blocks[x][y];
                var _position4 = _this6.positions[x - 1][y]; //下边的那个格子
                _this6.blocks[x - 1][y] = _block4;
                _this6.data[x - 1][y] = _this6.data[x][y];
                _this6.data[x][y] = 0;
                _this6.blocks[x][y] = null;
                _this6.doMove(_block4, _position4, function () {
                    move(x - 1, y, callback);
                });
                hasMoved = true;
            } else {
                callback && callback();
                return;
            }
        };

        //移动这些块
        var counter = 0;
        for (var _i5 = 0; _i5 < toMove.length; _i5++) {
            move(toMove[_i5].x, toMove[_i5].y, function () {
                ++counter;
                if (counter == toMove.length) {
                    _this6.afterMove(hasMoved);
                }
            });
        }
    }
});

cc._RF.pop();